#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../src/queue.h"


// printf("%-64s", "\x1b[33m" # func "\x1b[0m");
#define test(func) \
    printf("... %-64s", "\033[1;33m" #func "\033[0m");      \
    test_##func();                              \
    printf("\033[1;32m ok \033[0m\n")


void test_queue_create()
{
    queue_t *q;
    q = queue_create(10);
    assert(q != NULL);
    assert(q->data != NULL);
    assert(q->head == 0);
    assert(q->tail == 0);
    assert(q->cnt == 0);
    assert(q->size == 16);
    assert(q->mask == 15);
    queue_destroy(q);
    q = NULL;

    q = queue_create(8);
    assert(q != NULL);
    assert(q->data != NULL);
    assert(q->head == 0);
    assert(q->tail == 0);
    assert(q->cnt == 0);
    assert(q->size == 8);
    assert(q->mask == 7);
    queue_destroy(q);
}


void test_enqueue()
{
    queue_t *q = queue_create(3);
    assert(q != NULL);
    assert(q->data != NULL);
    assert(q->head == 0);
    assert(q->tail == 0);
    assert(q->cnt == 0);
    assert(q->size == 4);
    assert(q->mask == 3);

    char *a = "foo";
    char *b = "tar";
    char *c = "pop";
    char *d = "wwe";
    char *e = "hai";

    enqueue(q, a);
    assert(q->head == 1);
    enqueue(q, b);
    assert(q->head == 2);
    enqueue(q, c);
    assert(q->head == 3);
    enqueue(q, d);
    assert(q->head == 0);

    assert(q->cnt == 4);
    assert(q->tail == 0);
    assert(queue_is_full(q) == 1);

    assert(q->data[0] == a);
    assert(q->data[1] == b);
    assert(q->data[2] == c);
    assert(q->data[3] == d);

    assert(enqueue(q, e) == -1);

    queue_destroy(q);
}


void test_dequeue()
{
    queue_t *q = queue_create(3);
    assert(q != NULL);
    assert(q->data != NULL);
    assert(q->head == 0);
    assert(q->tail == 0);
    assert(q->cnt == 0);
    assert(q->size == 4);
    assert(q->mask == 3);

    char *a = "foo";
    char *b = "tar";
    char *c = "pop";
    char *d = "wwe";
    char *e = "hai";

    enqueue(q, a);
    enqueue(q, b);
    enqueue(q, c);
    enqueue(q, d);

    assert(enqueue(q, e) == -1);

    assert(dequeue(q) == a);
    assert(q->cnt == 3);
    assert(q->tail == 1);

    assert(dequeue(q) == b);
    assert(q->cnt == 2);
    assert(q->tail == 2);

    assert(dequeue(q) == c);
    assert(q->cnt == 1);
    assert(q->tail == 3);

    assert(dequeue(q) == d);
    assert(q->cnt == 0);
    assert(q->tail == 0);

    assert(dequeue(q) == NULL);

    queue_destroy(q);
}


int main(int argc, char *argv[])
{
    test(queue_create);
    test(enqueue);
    test(dequeue);

    puts("... \x1b[32m100%\x1b[0m\n");
    return 0;
}



